package com.jl15988.mybatispluskit.join.example;

import com.jl15988.mybatispluskit.join.service.BaseJoinService;
import com.jl15988.mybatispluskit.join.wrapper.JoinLambdaWrapper;

import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;

/**
 * 关联查询使用示例
 * 展示各种关联查询的用法
 * 
 * @author Jalon
 * @since 2025/1/1
 */
@Service
public class UsageExample {
    
    // 假设的实体类
    public static class User {
        private Long id;
        private String username;
        private String email;
        private Long deptId;
        private Integer status;
        
        // getter/setter 省略...
        public Long getId() { return id; }
        public void setId(Long id) { this.id = id; }
        public String getUsername() { return username; }
        public void setUsername(String username) { this.username = username; }
        public String getEmail() { return email; }
        public void setEmail(String email) { this.email = email; }
        public Long getDeptId() { return deptId; }
        public void setDeptId(Long deptId) { this.deptId = deptId; }
        public Integer getStatus() { return status; }
        public void setStatus(Integer status) { this.status = status; }
    }
    
    public static class Department {
        private Long id;
        private String name;
        private String code;
        private Integer status;
        
        // getter/setter 省略...
        public Long getId() { return id; }
        public void setId(Long id) { this.id = id; }
        public String getName() { return name; }
        public void setName(String name) { this.name = name; }
        public String getCode() { return code; }
        public void setCode(String code) { this.code = code; }
        public Integer getStatus() { return status; }
        public void setStatus(Integer status) { this.status = status; }
    }
    
    public static class Role {
        private Long id;
        private String name;
        private String code;
        private Integer status;
        
        // getter/setter 省略...
        public Long getId() { return id; }
        public void setId(Long id) { this.id = id; }
        public String getName() { return name; }
        public void setName(String name) { this.name = name; }
        public String getCode() { return code; }
        public void setCode(String code) { this.code = code; }
        public Integer getStatus() { return status; }
        public void setStatus(Integer status) { this.status = status; }
    }
    
    public static class UserRole {
        private Long id;
        private Long userId;
        private Long roleId;
        
        // getter/setter 省略...
        public Long getId() { return id; }
        public void setId(Long id) { this.id = id; }
        public Long getUserId() { return userId; }
        public void setUserId(Long userId) { this.userId = userId; }
        public Long getRoleId() { return roleId; }
        public void setRoleId(Long roleId) { this.roleId = roleId; }
    }
    
    // 假设注入的服务
    private BaseJoinService<User> userService;
    
    /**
     * 示例1：基本的左连接查询
     * 查询用户及其部门信息
     */
    public void example1_BasicLeftJoin() {
        // 使用 JoinLambdaWrapper
        JoinLambdaWrapper<User> wrapper = new JoinLambdaWrapper<User>()
                .leftJoin(Department.class, User::getDeptId, Department::getId)  // 左连接部门表
                .eq(User::getStatus, 1)  // 用户状态为启用
                .eq(Department::getStatus, 1);  // 部门状态为启用
        
        List<User> users = userService.listJoin(wrapper);
    }
    
    /**
     * 示例2：多表关联查询
     * 查询用户、部门、角色信息
     */
    public void example2_MultiTableJoin() {
        JoinLambdaWrapper<User> wrapper = new JoinLambdaWrapper<User>()
                .leftJoin(Department.class, User::getDeptId, Department::getId)      // 关联部门
                .leftJoin(UserRole.class, User::getId, UserRole::getUserId)          // 关联用户角色
                .leftJoin(Role.class, UserRole::getRoleId, Role::getId)              // 关联角色
                .eq(User::getStatus, 1)                                              // 用户状态条件
                .eq(Department::getStatus, 1)                  // 部门状态条件
                .eq(Role::getStatus, 1);                             // 角色状态条件
        
        List<User> users = userService.listJoin(wrapper);
    }
    
    /**
     * 示例3：内连接查询
     * 只查询有部门的用户
     */
    public void example3_InnerJoin() {
        JoinLambdaWrapper<User> wrapper = new JoinLambdaWrapper<User>()
                .innerJoin(Department.class, User::getDeptId, Department::getId)  // 内连接，确保用户有部门
                .eq(User::getStatus, 1)
                .like(Department::getName, "技术");  // 部门名称包含"技术"
        
        List<User> users = userService.listJoin(wrapper);
    }
    
    /**
     * 示例4：复杂查询条件
     * 多种条件组合查询
     */
    public void example4_ComplexConditions() {
        JoinLambdaWrapper<User> wrapper = new JoinLambdaWrapper<User>()
                .leftJoin(Department.class, User::getDeptId, Department::getId)
                .eq(User::getStatus, 1)                                    // 用户启用
                .like(User::getUsername, "admin")                          // 用户名包含admin
                .ne(User::getEmail, "")                                    // 邮箱不为空
                .eq(Department::getStatus, 1)        // 部门启用
                .ne(Department::getCode, "")         // 部门编码不为空
                .like(Department::getName, "开发");   // 部门名称包含开发
        
        List<User> users = userService.listJoin(wrapper);
    }
    
    /**
     * 示例5：查询记录数
     * 统计符合条件的记录数量
     */
    public void example5_Count() {
        JoinLambdaWrapper<User> wrapper = new JoinLambdaWrapper<User>()
                .leftJoin(Department.class, User::getDeptId, Department::getId)
                .eq(User::getStatus, 1)
                .eq(Department::getStatus, 1);
        
        long count = userService.countJoin(wrapper);
        System.out.println("符合条件的用户数量: " + count);
    }
    
    /**
     * 示例6：查询单条记录
     * 根据条件查询唯一记录
     */
    public void example6_SelectOne() {
        JoinLambdaWrapper<User> wrapper = new JoinLambdaWrapper<User>()
                .leftJoin(Department.class, User::getDeptId, Department::getId)
                .eq(User::getId, 1L);  // 根据用户ID查询
        
        User user = userService.getOneJoin(wrapper);
    }
    
    /**
     * 示例7：查询自定义字段组合
     * 返回 Map 结果，包含多表字段
     */
    public void example7_SelectMaps() {
        JoinLambdaWrapper<User> wrapper = new JoinLambdaWrapper<User>()
                .select("t0.id, t0.username, t0.email, t1.name as dept_name")  // 自定义查询字段
                .leftJoin(Department.class, User::getDeptId, Department::getId)
                .eq(User::getStatus, 1);
        
        List<Map<String, Object>> results = userService.listJoinMaps(wrapper);
        
        // 结果示例：
        // [
        //   {id=1, username="admin", email="admin@example.com", dept_name="技术部"},
        //   {id=2, username="user1", email="user1@example.com", dept_name="市场部"}
        // ]
    }
    
    /**
     * 示例8：设置主表别名
     * 自定义主表别名
     */
    public void example8_CustomAlias() {
        JoinLambdaWrapper<User> wrapper = new JoinLambdaWrapper<User>()
                .setMainTableAlias("u")  // 设置主表别名为 u
                .leftJoin(Department.class, User::getDeptId, Department::getId)  // 关联表自动分配别名 t1
                .eq(User::getStatus, 1);
        
        List<User> users = userService.listJoin(wrapper);
    }
    
    /**
     * 示例9：多种连接类型组合
     * 在一个查询中使用多种连接类型
     */
    public void example9_MixedJoinTypes() {
        JoinLambdaWrapper<User> wrapper = new JoinLambdaWrapper<User>()
                .innerJoin(Department.class, User::getDeptId, Department::getId)     // 内连接部门（必须有部门）
                .leftJoin(UserRole.class, User::getId, UserRole::getUserId)          // 左连接角色（可能没有角色）
                .leftJoin(Role.class, UserRole::getRoleId, Role::getId)              // 左连接角色表
                .eq(User::getStatus, 1)
                .eq(Department::getStatus, 1);
        
        List<User> users = userService.listJoin(wrapper);
    }
} 